/*
 * @Author: your name
 * @Date: 2021-01-28 10:54:54
 * @LastEditTime: 2021-04-17 16:37:48
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \tower_defense\assets\scripts\game_scene\tower\arrow_bullet.ts
 */

import { UG } from "../../modules/ugame"
import { ArrowBulletParams } from "../../game_data/tower_data/arrow_bullet_params";
import Enemy from "../enemy/enemy";

const { ccclass, property } = cc._decorator;

@ccclass
export class ArrowBullet extends cc.Component {

    @property(cc.Integer)   // 子弹移动速度
    public speed: number = 200;

    @property(cc.Integer)   // 子弹攻击力
    public attack: number = 10;

    @property(cc.Integer)   // 子弹等级
    public bullet_level: number = 1;

    @property(cc.SpriteFrame)   // 子弹完整图
    public arrow_bullet_sf: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)   // 子弹半截图
    public arrpw_bullet_half_sf: cc.SpriteFrame = null;

    @property(cc.Node)          // 子弹精灵节点
    public anim_node: cc.Node = null;

    public bullet_root_node: cc.Node = null;    // 子弹存放节点
    public shoot_enemy: cc.Node = null;         // 敌人

    onLoad() {
        this.bullet_root_node = cc.find('Canvas/tower_panel/bullet_root');
    }

    // 子弹射击
    public shoot(level: number, archer_pos: cc.Vec2, enemy_pos: cc.Vec2, enemy: cc.Node): void {
        // 子弹参数
        this.bullet_level = level;
        this.speed = ArrowBulletParams[this.bullet_level - 1].speed;
        this.attack = ArrowBulletParams[this.bullet_level - 1].attack;
        this.shoot_enemy = enemy;
        // 把敌人、弓箭手的世界坐标，转换成和子弹同一个坐标系下
        let start_pos: cc.Vec2 = this.bullet_root_node.parent.convertToNodeSpaceAR(archer_pos);
        let end_pos: cc.Vec2 = this.bullet_root_node.parent.convertToNodeSpaceAR(enemy_pos);

        // 调整角度 位置
        this.node.setPosition(start_pos);
        this.anim_node.angle = -90;      // 弓箭方向朝上

        // 贝塞尔曲线的方式移动子弹
        let dir: cc.Vec2 = enemy_pos.sub(archer_pos);   // 移动方向
        let len: number = dir.mag();                    // 向量差长度
        let time: number = len / this.speed;            // 求运动时间

        if (this.shoot_enemy) {
            let enemy_com: Enemy = this.shoot_enemy.getComponent(Enemy);
            end_pos = enemy_com.walk_pos_by_time(time);
        }

        // cocos中bezierTo是三阶贝塞尔 两个控制点,起点,终点
        let ctrl: cc.Vec2 = cc.v2();
        // 取中点做控制点,垂直方向y在起点和终点中取较大值
        ctrl.x = (start_pos.x + end_pos.x) * 0.5;     // 水平方向取中点值
        ctrl.y = (end_pos.y > start_pos.y) ? end_pos.y : start_pos.y;   // 垂直方向取较大值
        ctrl.y += 40;   // 垂直方向拉高弧度

        // 执行弓箭贝塞尔运动
        cc.tween(this.node)
            .bezierTo(time, ctrl, ctrl, end_pos)
            .call(() => {   // 弓箭射到地上,显示半截弓箭
                let _anim_sprite: cc.Sprite = this.anim_node.getComponent(cc.Sprite);
                _anim_sprite.spriteFrame = this.arrpw_bullet_half_sf;
                // 弓箭判定伤害
                this._on_bullet_shoot_enemy(end_pos);
            })
            .delay(3)       // 弓箭延迟3秒消失
            .call(() => {
                // 移除弓箭
                this.node.destroy(); 
            })
            .start();

        // 贝塞尔运动得同时调整弓箭角度
        let degree: number = 0;
        // 判断射箭是往左还是往右
        degree = (end_pos.x < start_pos.x) ? (180 - Math.random() * 10) : (-180 + Math.random() * 10);
        cc.tween(this.anim_node)
            .by(time, { angle: degree })
            .start();
    };

    // 弓箭射中敌人
    private _on_bullet_shoot_enemy(enemy_pos: cc.Vec2): void {
        // cc.log('射中敌人');
        if (!this.shoot_enemy || !UG.is_enemy_active(this.shoot_enemy)) {
            return;
        }

        // 击中怪物
        let enemy: Enemy = this.shoot_enemy.getComponent(Enemy);
        enemy.on_arrow_attacked(ArrowBulletParams[this.bullet_level - 1].attack);
        
        // 移除子弹，可以改用节点池
        this.node.removeFromParent();
    }

}
